package instantHelper.ClosedMode;

import instantHelper.Models.CustomHttpClient;
import instantHelper.NormalMode.MyLocationListener;
import instantHelper.Raceway.ClosedMode;
import instantHelper.Raceway.DbHelper;
import instantHelper.Raceway.FTPHelper;
import instantHelper.Raceway.InstantHelperConstant;
import instantHelper.Raceway.R;
import instantHelper.Raceway.SettingsUtil;
import instantHelper.Raceway.R.id;
import instantHelper.Raceway.R.layout;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.ActivityInfo;
import android.database.sqlite.SQLiteDatabase;
import android.location.LocationManager;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

public class ClosedModeVideoCapture extends Activity implements
		OnClickListener, SurfaceHolder.Callback {
	MediaRecorder recorder;
	SurfaceHolder holder;
	boolean recording = false;
	int maxDuration;
	String requestId = "";
	String androidId = "";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		Bundle extras = getIntent().getExtras();
		handleScreenLightDark();
		if (extras != null) {
			requestId = extras.getString("requestId");
		}
		androidId = SettingsUtil.getAndroidID(getApplicationContext());

		MyLocationListener.getGPSData(getApplicationContext(), androidId,
				requestId);

		maxDuration = Integer.parseInt(SettingsUtil
				.getVideoMaximumDuration(getApplicationContext()));
		setContentView(R.layout.video);
		SurfaceView cameraView = (SurfaceView) findViewById(R.id.CameraView);
		holder = cameraView.getHolder();
		holder.addCallback(this);
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

	}

	private void releaseCamera(String fileName) {
		try {
			Thread.sleep(maxDuration * 1000);
			recorder.stop();
			recorder.release();
			sendVideo(fileName);
		} catch (Exception e) {
		}
	}

	private void captureVideos(SurfaceHolder holder) {
		for (int i = 0; i < 5; i++) {
			initRecorder("video_" + requestId + "_" + i);
			prepareRecorder();
			recorder.start();
			recording = true;
			releaseCamera("video_" + requestId + "_" + i);
		}
		surfaceDestroyed(holder);
	}

	private void sendVideo(String fileName) {
		String result = sendHelpRequestVideo(fileName + ".mp4", requestId);
		if (result.equals("successfull")) {

			boolean issend = FTPHelper.sendToServer(
					"/sdcard/ihcenterapp/videos/" + fileName + ".mp4",
					"videos/");
			if (!issend) {
				insertDirectoryTable(fileName + ".mp4", false);
			} else {
				if (SettingsUtil.getDeleteDataControl(getApplicationContext())) {
					SettingsUtil.deleteFile("/sdcard/ihcenterapp/videos/"
							+ fileName + ".mp4");
				}
			}
		}
	}

	private void insertDirectoryTable(String path, boolean issend) {
		ContentValues contentValues = new ContentValues();
		contentValues.put(InstantHelperConstant.DB_DIRECTORY_PATH, path);
		contentValues.put(InstantHelperConstant.DB_DIRECTORY_REQUEST_ID,
				requestId);
		contentValues.put(InstantHelperConstant.DB_DIRECTORY_TYPE, "video");
		contentValues.put(InstantHelperConstant.DB_DIRECTORY_ISSEND, issend);
		Date date = new Date();
		contentValues.put(InstantHelperConstant.DB_DIRECTORY_DATE,
				date.toString());

		DbHelper myDbHelper = new DbHelper(ClosedModeVideoCapture.this);
		SQLiteDatabase db = myDbHelper.getWritableDatabase();

		try {
			db.insertOrThrow(InstantHelperConstant.DB_DIRECTORY_TABLE, null,
					contentValues);

		} catch (Exception e) {
		}
	}

	private String sendHelpRequestVideo(String videoPath, String requesId) {
		String url = InstantHelperConstant.CentralAppURL
				+ "/androidhelprequest/newVideo";

		ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
		postParameters.add(new BasicNameValuePair("requestId", requesId));
		postParameters.add(new BasicNameValuePair("videoPath", videoPath));
		postParameters.add(new BasicNameValuePair("androidId", androidId));
		String response = null;
		String result = "";
		try {
			response = CustomHttpClient.executeHttpPost(url, postParameters);
			String res = response.toString();
			JSONObject jObject = new JSONObject(res);
			result = jObject.getString("result");
		} catch (Exception e) {
		}
		return result;
	}

	private void initRecorder(String fileName) {
		recorder = new MediaRecorder();
		recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
		recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
		String videoQuality = SettingsUtil
				.getVideoQuality(getApplicationContext());
		CamcorderProfile cpHigh;
		if (videoQuality.equals("Low")) {
			cpHigh = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
		} else if (videoQuality.equals("High")) {
			cpHigh = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
		} else {
			cpHigh = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
		}

		recorder.setProfile(cpHigh);
		recorder.setOutputFile("/sdcard/ihcenterapp/videos/" + fileName
				+ ".mp4");
		int maxDuration = Integer.parseInt(SettingsUtil
				.getVideoMaximumDuration(getApplicationContext()));
		recorder.setMaxDuration(maxDuration * 1000); // 50 seconds
		// recorder.setMaxFileSize(5000000); // Approximately 5 megabytes
	}

	private void prepareRecorder() {
		recorder.setPreviewDisplay(holder.getSurface());
		try {
			recorder.prepare();
		} catch (IllegalStateException e) {
			e.printStackTrace();
			finish();
		} catch (IOException e) {
			e.printStackTrace();
			finish();
		}
	}

	public void surfaceCreated(SurfaceHolder holder) {
		captureVideos(holder);
	}

	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		handleScreenLightOpen();
		if (recording) {
			recorder.stop();
			recording = false;
		}
		recorder.release();
		finish();
	}

	@Override
	public void onClick(DialogInterface arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	private void handleScreenLightDark() {
		Settings.System.putInt(getContentResolver(),
				Settings.System.SCREEN_BRIGHTNESS_MODE,
				Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
		android.provider.Settings.System.putInt(getContentResolver(),
				android.provider.Settings.System.SCREEN_BRIGHTNESS, 0);
		WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
		layoutParams.screenBrightness = 0F;
		layoutParams.buttonBrightness = 0F;
		getWindow().setAttributes(layoutParams);
	}

	private void handleScreenLightOpen() {
		Settings.System.putInt(getContentResolver(),
				Settings.System.SCREEN_BRIGHTNESS_MODE,
				Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
		int lev = fractionToSetting(1F);
		Settings.System.putInt(getContentResolver(),
				Settings.System.SCREEN_BRIGHTNESS, lev);
	}

	private static final float LEVEL_MIN = 0.06f;
	private static final float LEVEL_RANGE = 1f - LEVEL_MIN;

	// BrightnessSettings values: fully off, dim, fully on.
	private static final int SETTING_MAX = 255;

	static final float settingToFraction(int setting) {
		float base = (float) setting / (float) SETTING_MAX;
		return (base - LEVEL_MIN) / LEVEL_RANGE;
	}

	static final int fractionToSetting(float frac) {
		float actual = frac * LEVEL_RANGE + LEVEL_MIN;
		return Math.round(actual * SETTING_MAX);
	}
}
